home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / source / qmail-queue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-09  |  5.9 KB  |  266 lines

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include "readwrite.h"
  4. #include "sig.h"
  5. #include "exit.h"
  6. #include "open.h"
  7. #include "seek.h"
  8. #include "fmt.h"
  9. #include "alloc.h"
  10. #include "substdio.h"
  11. #include "datetime.h"
  12. #include "now.h"
  13. #include "triggerpull.h"
  14. #include "extra.h"
  15. #include "auto_qmail.h"
  16. #include "auto_uids.h"
  17. #include "date822fmt.h"
  18. #include "fmtqfn.h"
  19.  
  20. #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */
  21. #define ADDR 1003
  22.  
  23. char inbuf[2048];
  24. struct substdio ssin;
  25. char outbuf[256];
  26. struct substdio ssout;
  27.  
  28. datetime_sec starttime;
  29. struct datetime dt;
  30. unsigned long mypid;
  31. unsigned long uid;
  32. char *pidfn;
  33. struct stat pidst;
  34. unsigned long messnum;
  35. char *messfn;
  36. char *todofn;
  37. char *intdfn;
  38. int messfd;
  39. int intdfd;
  40. int flagmademess = 0;
  41. int flagmadeintd = 0;
  42.  
  43. void cleanup()
  44. {
  45.  if (flagmadeintd)
  46.   {
  47.    seek_trunc(intdfd,0);
  48.    if (unlink(intdfn) == -1) return;
  49.   }
  50.  if (flagmademess)
  51.   {
  52.    seek_trunc(messfd,0);
  53.    if (unlink(messfn) == -1) return;
  54.   }
  55. }
  56.  
  57. void die(e) int e; { _exit(e); }
  58. void die_write() { cleanup(); die(122); }
  59. void die_read() { cleanup(); die(121); }
  60. void sigalrm() { /* thou shalt not clean up here */ die(124); }
  61. void sigbug() { die(101); }
  62.  
  63. unsigned int receivedlen;
  64. char *received;
  65. /* "Received: (qmail-queue invoked by alias); 26 Sep 1995 04:46:54 -0000\n" */
  66.  
  67. static unsigned int receivedfmt(s)
  68. char *s;
  69. {
  70.  unsigned int i;
  71.  unsigned int len;
  72.  len = 0;
  73.  i = fmt_str(s,"Received: (qmail "); len += i; if (s) s += i;
  74.  i = fmt_ulong(s,mypid); len += i; if (s) s += i;
  75.  i = fmt_str(s," invoked "); len += i; if (s) s += i;
  76.  if (uid == auto_uida)
  77.   { i = fmt_str(s,"by alias"); len += i; if (s) s += i; }
  78.  else if (uid == auto_uidd)
  79.   { i = fmt_str(s,"from network"); len += i; if (s) s += i; }
  80.  else if (uid == auto_uids)
  81.   { i = fmt_str(s,"for bounce"); len += i; if (s) s += i; }
  82.  else
  83.   {
  84.    i = fmt_str(s,"by uid "); len += i; if (s) s += i;
  85.    i = fmt_ulong(s,uid); len += i; if (s) s += i;
  86.   }
  87.  i = fmt_str(s,"); "); len += i; if (s) s += i;
  88.  i = date822fmt(s,&dt); len += i; if (s) s += i;
  89.  return len;
  90. }
  91.  
  92. void received_setup()
  93. {
  94.  receivedlen = receivedfmt((char *) 0);
  95.  received = alloc(receivedlen + 1);
  96.  if (!received) die(123);
  97.  receivedfmt(received);
  98. }
  99.  
  100. unsigned int pidfmt(s,seq)
  101. char *s;
  102. unsigned long seq;
  103. {
  104.  unsigned int i;
  105.  unsigned int len;
  106.  
  107.  len = 0;
  108.  i = fmt_str(s,"pid/"); len += i; if (s) s += i;
  109.  i = fmt_ulong(s,mypid); len += i; if (s) s += i;
  110.  i = fmt_str(s,"."); len += i; if (s) s += i;
  111.  i = fmt_ulong(s,starttime); len += i; if (s) s += i;
  112.  i = fmt_str(s,"."); len += i; if (s) s += i;
  113.  i = fmt_ulong(s,seq); len += i; if (s) s += i;
  114.  ++len; if (s) *s++ = 0;
  115.  
  116.  return len;
  117. }
  118.  
  119. char *fnnum(dirslash,flagsplit)
  120. char *dirslash;
  121. int flagsplit;
  122. {
  123.  char *s;
  124.  
  125.  s = alloc(fmtqfn((char *) 0,dirslash,messnum,flagsplit));
  126.  if (!s) die(123);
  127.  fmtqfn(s,dirslash,messnum,flagsplit);
  128.  return s;
  129. }
  130.  
  131. void pidopen()
  132. {
  133.  unsigned int len;
  134.  unsigned long seq;
  135.  
  136.  seq = 1;
  137.  len = pidfmt((char *) 0,seq);
  138.  pidfn = alloc(len);
  139.  if (!pidfn) die(123);
  140.  
  141.  for (seq = 1;seq < 10;++seq)
  142.   {
  143.    if (pidfmt((char *) 0,seq) > len) die(101); /* paranoia */
  144.    pidfmt(pidfn,seq);
  145.    messfd = open_excl(pidfn);
  146.    if (messfd != -1) return;
  147.   }
  148.  
  149.  die(103);
  150. }
  151.  
  152. char tmp[FMT_ULONG];
  153.  
  154. void main()
  155. {
  156.  unsigned int len;
  157.  char ch;
  158.  
  159.  sig_blocknone();
  160.  umask(033);
  161.  if (chdir(auto_qmail) == -1) die(102);
  162.  if (chdir("queue") == -1) die(102);
  163.  
  164.  mypid = getpid();
  165.  uid = getuid();
  166.  starttime = now();
  167.  datetime_tai(&dt,starttime);
  168.  
  169.  received_setup();
  170.  
  171.  sig_pipeignore();
  172.  sig_miscignore();
  173.  sig_alarmcatch(sigalrm);
  174.  sig_bugcatch(sigbug);
  175.  
  176.  alarm(DEATH);
  177.  
  178.  pidopen();
  179.  if (fstat(messfd,&pidst) == -1) die(104);
  180.  
  181.  messnum = pidst.st_ino;
  182.  messfn = fnnum("mess/",1);
  183.  todofn = fnnum("todo/",0);
  184.  intdfn = fnnum("intd/",0);
  185.  
  186.  if (rename (pidfn, messfn) == -1) die (105);
  187.  flagmademess = 1;
  188.  
  189.  substdio_fdbuf(&ssout,write,messfd,outbuf,sizeof(outbuf));
  190.  substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
  191.  
  192.  if (uid != auto_uidd)
  193.    if (substdio_bput(&ssout,received,receivedlen) == -1) die_write();
  194.  
  195.  switch(substdio_copy(&ssout,&ssin))
  196.   {
  197.    case -2: die_read();
  198.    case -3: die_write();
  199.   }
  200.  
  201.  if (substdio_flush(&ssout) == -1) die_write();
  202.  if (fsync(messfd) == -1) die_write();
  203.  
  204.  intdfd = open_excl(intdfn);
  205.  if (intdfd == -1) die(108);
  206.  flagmadeintd = 1;
  207.  
  208.  substdio_fdbuf(&ssout,write,intdfd,outbuf,sizeof(outbuf));
  209.  substdio_fdbuf(&ssin,read,1,inbuf,sizeof(inbuf));
  210.  
  211.  if (substdio_bput(&ssout,"u",1) == -1) die_write();
  212.  if (substdio_bput(&ssout,tmp,fmt_ulong(tmp,uid)) == -1) die_write();
  213.  if (substdio_bput(&ssout,"",1) == -1) die_write();
  214.  
  215.  if (substdio_bput(&ssout,"p",1) == -1) die_write();
  216.  if (substdio_bput(&ssout,tmp,fmt_ulong(tmp,mypid)) == -1) die_write();
  217.  if (substdio_bput(&ssout,"",1) == -1) die_write();
  218.  
  219.  if (substdio_get(&ssin,&ch,1) < 1) die_read();
  220.  if (ch != 'F') die(112);
  221.  if (substdio_bput(&ssout,&ch,1) == -1) die_write();
  222.  for (len = 0;len < ADDR;++len)
  223.   {
  224.    if (substdio_get(&ssin,&ch,1) < 1) die_read();
  225.    if (substdio_put(&ssout,&ch,1) == -1) die_write();
  226.    if (!ch) break;
  227.   }
  228.  if (len >= ADDR) die(115);
  229.  
  230.  if (substdio_bput(&ssout,QUEUE_EXTRA,QUEUE_EXTRALEN) == -1) die_write();
  231.  
  232.  for (;;)
  233.   {
  234.    if (substdio_get(&ssin,&ch,1) < 1) die_read();
  235.    if (!ch) break;
  236.    if (ch != 'T') die(112);
  237.    if (substdio_bput(&ssout,&ch,1) == -1) die_write();
  238.    for (len = 0;len < ADDR;++len)
  239.     {
  240.      if (substdio_get(&ssin,&ch,1) < 1) die_read();
  241.      if (substdio_bput(&ssout,&ch,1) == -1) die_write();
  242.      if (!ch) break;
  243.     }
  244.    if (len >= ADDR) die(115);
  245.   }
  246.  
  247.  if (substdio_flush(&ssout) == -1) die_write();
  248.  if (fsync(intdfd) == -1) die_write();
  249.  
  250. /* #ifdef __amigaos__
  251.  if (fchown (messfd, auto_uidq, -1) == -1) die(106);
  252.  if (fchown (intdfd, auto_uidq, -1) == -1) die(106);
  253. #endif */
  254.  if (close (messfd) == -1) die(106);
  255.  if (close (intdfd) == -1) die(106);
  256. #ifdef __amigaos__
  257.  chown (messfn, auto_uidq, -1);
  258.  chown (intdfn, auto_uidq, -1);
  259. #endif
  260.  
  261.  if (link(intdfn,todofn) == -1) die(106);
  262.  
  263.  triggerpull();
  264.  die(0);
  265. }
  266.